package lacus.wd_cinema.entity;

import jakarta.persistence.*;
import jakarta.validation.constraints.PositiveOrZero;
import lacus.wd_cinema.exception.ValidationException;
import lombok.Data;
import lombok.Getter;

import java.time.LocalDateTime;
import java.util.ArrayList;
import java.util.List;

/**
 * 放映场次实体类
 * @author lacus
 * @version 0.3
 * @since 0.3
 */
@Data
@Entity
@Table(name = "screening_tbl")
public class Screening {
    @Id
    @Column(name = "id")
    private String id;

    @ManyToOne
    @JoinColumn(name = "hall_id")
    private Hall hall;

    @ManyToOne
    @JoinColumn(name = "movie_id")
    private Movie movie;

    @Column(name = "start_time")
    private LocalDateTime startTime;

    @Column(name = "end_time")
    private LocalDateTime endTime;

    @PositiveOrZero(message = "票价不能为负数")
    @Column(name = "ticket_price")
    private int ticketPrice;

    @OneToMany(mappedBy = "screening", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<Ticket> tickets = new ArrayList<>();

    @Column(name = "status")
    private Status status = Status.ON_SCHEDULE;

    @Getter
    public enum Status {
        ON_SCHEDULE("未开始售票"),
        ON_SALE("已开始售票"),
        SALE_STOPPED("已停止售票"),
        IN_PROGRESS("正在放映中"),
        COMPLETED("放映已结束");

        private final String displayName;

        Status(String displayName) {
            this.displayName = displayName;
        }
    }

    public void setEndTime() {
        endTime = startTime.plus(movie.getRuntime());
    }

    /** 将价格转换字符串 */
    public String formatPrice() {
        return String.format("%.2f", (double) ticketPrice / 100);
    }

    /** 将价格转换为存储的整数类型 */
    public void parsePrice(String ticketPrice) {
        try {
            this.ticketPrice = (int) (Double.parseDouble(ticketPrice) * 100);
        } catch (NumberFormatException e) {
            throw new ValidationException("票价输入格式不正确");
        }
    }

    /** 计算已售出票数 */
    public int countOfSoldTickets() {
        return tickets.stream().filter(Ticket::isNotRefunded).toList().size();
    }

    /** 计算退票数 */
    public int countOfRefundedTickets() {
        return tickets.stream().filter(Ticket::isRefunded).toList().size();
    }

    /** 判断放映是否处于未开放售票状态 */
    public boolean isOnSchedule() {
        return status == Status.ON_SCHEDULE;
    }
}
